﻿#ifndef _NETIF_H_
#define _NETIF_H_

#include "debug.h"
#include "ipaddr.h"
#include "fixq.h"
#include "nlist.h"
#include "pktbuf.h"

// 硬件地址类型
typedef struct _netif_hwaddr_t
{
    uint8_t addr[NETIF_HWADDR_SIZE]; // 硬件地址
    uint8_t len;                     // 地址长度
} netif_hwaddr_t;

// 网络接口类型
typedef enum _netif_type_t
{
    NETIF_TYPE_NONE = 0,
    NETIF_TYPE_ETHER, // 以太网
    NETIF_TYPE_LOOP,  // 环回网络接口
    NETIF_TYPE_SIZE
} netif_type_t;

struct _netif_t;

typedef struct _netif_ops_t
{
    net_err_t (*open)(struct _netif_t *netif, void *data);
    void (*close)(struct _netif_t *netif);
    net_err_t (*xmit)(struct _netif_t *netif);
} netif_ops_t;

// 链路层相关的回调函数指针
typedef struct _link_layer_t
{
    netif_type_t type;
    net_err_t (*open)(struct _netif_t *netif);
    net_err_t (*close)(struct _netif_t *netif);
    net_err_t (*in)(struct _netif_t *netif, pktbuf_t *buf);
    net_err_t (*out)(struct _netif_t *netif, ipaddr_t *des, pktbuf_t *buf);
} link_layer_t;

// 网卡结构类型
typedef struct _netif_t
{
    char name[NETIF_NAME_SIZE]; // 网卡名称

    netif_hwaddr_t hwaddr; // 硬件地址
    ipaddr_t ipaddr;       // ip地址
    ipaddr_t netmask;      // 掩码
    ipaddr_t gateway;      // 网关

    netif_type_t type; // 网络接口类型
    int mtu;           // 最大传输单元
    nlist_node_t node; // 可以以链表的形式存储网络接口
    fixq_t in_q;       // 输入队列，用于和核心工作线程之间的交互
    fixq_t out_q;      // 输出队列
    void *in_q_buf[NETIF_INQ_SIZE];
    void *out_q_buf[NETIF_OUTQ_SIZE];

    const netif_ops_t *ops; // 网络接口打开硬件层面相关操作
    void *ops_data;

    const link_layer_t *layer;

    // 网络接口的状态
    enum
    {
        NETIF_CLOSED,
        NETIF_OPENED,
        NETIF_ACTIVE
    } state;
} netif_t;

net_err_t netif_init();
netif_t *netif_open(const char *name, const netif_ops_t *ops, void *ops_data);
net_err_t netif_set_addr(netif_t *netif, ipaddr_t *ip, ipaddr_t *mask, ipaddr_t *gateway);
net_err_t netif_set_hwaddr(netif_t *netif, const char *hwaddr, int len);
net_err_t netif_set_active(netif_t *netif);
net_err_t netif_set_deactive(netif_t *netif);
net_err_t netif_set_default(netif_t *netif);
netif_t *netif_get_default();
net_err_t netif_close(netif_t *netif);

// 网络接口对消息队列的处理
net_err_t netif_put_in(netif_t *netif, pktbuf_t *buf, int tmo);
pktbuf_t *netif_get_in(netif_t *netif, int tmo);
net_err_t netif_put_out(netif_t *netif, pktbuf_t *buf, int tmo);
pktbuf_t *netif_get_out(netif_t *netif, int tmo);
net_err_t netif_out(netif_t *netif, ipaddr_t *ipaddr, pktbuf_t *buf);

net_err_t netif_register_layer(netif_type_t type, const link_layer_t *layer);

void display_netif_list();
#endif